/* entity */
import Field from '@model/entity/Field'
/* util */
import * as FormUtil from '@src/component/form/util'
import { isString } from '@src/util/type'
/* vue */
import { EmitEvent } from '@model/VC'
import { ref, Ref } from 'vue'

export type UpdateFormDataType = {
  field: Field,
  newValue: Record<string, any>,
  oldValue: Record<string, any>
}

export enum useFormEventEnum {
  Input = 'input',
  Update = 'update'
}

/**
 * @description 表单组件数据更新提交事件方法
 * @param {EmitEvent} emit 提交事件方法
 * @param {Field} field 数据更改的字段
 * @param {Record<string, any>} newValue 数据变化后的新值
 * @param {Record<string, any>} oldValue 数据变化前的旧值
 * @return {void}
 */
export function useFormComponentUpdatedEmitEvent<NewValueType extends Record<string, any>, OldValueType extends Record<string, any>>(
  emit: EmitEvent, field: Field, newValue: NewValueType, oldValue?: OldValueType
): void {
  emit(useFormEventEnum.Update, { newValue, field, oldValue })
  emit(useFormEventEnum.Input, newValue)
}

/**
 * @description 表单数据更新提交事件方法
 * @param {EmitEvent} emit 提交事件方法
 * @param {Record<string, any>} newValue 数据变化后的新值
 * @param {Record<string, any>} oldValue 数据变化前的旧值
 * @return {void}
 */
export function useFormUpdatedEmitEvent<NewValueType extends Record<string, any>, OldValueType extends Record<string, any>>(
  emit: EmitEvent, newValue: NewValueType, oldValue?: OldValueType
): void {
  emit(useFormEventEnum.Update, newValue)
  emit(useFormEventEnum.Input, newValue)
}

export function useForm<T extends Record<string, any>>(fields: Field[], origin: Record<string, any>, emit: EmitEvent) {
  // 表单数据
  const form = ref(FormUtil.initialize(fields, origin, undefined))
  
  function resetForm() {
    form.value = FormUtil.initialize(fields, origin, undefined)
  }
  
  function updateForm(data: UpdateFormDataType) {
    let { field, newValue, oldValue } = data
    let { fieldName, displayName } = field;
    
    console.info(
      `[FormBuilder] ${displayName}(${fieldName}) : ${JSON.stringify(
        newValue
      )}`
    )
    
    const oldFormValue = form.value
    const newFormValue = {
      ...form.value,
      [fieldName]: isString(newValue) ? newValue.trim() : newValue
    }
    
    form.value = newFormValue
    
    useFormUpdatedEmitEvent(emit, newFormValue, oldFormValue)
    
  }
  
  return {
    form,
    resetForm,
    updateForm
  }
  
}